package com.zlsy.learning.leetcode.stack.s682;

import java.util.Stack;

/**
 * @author zhouliang
 * @date 2020/8/12 14:07
 */
public class CalPoints {
  public static void main(String[] args) {
    //    String[] ops = new String[] {"5", "2", "C", "D", "+"};
    String[] ops = new String[] {"5", "-2", "4", "C", "D", "9", "+", "+"};
    int i = calPoints(ops);
    System.out.println(i);
  }

  /** 栈+链表 */
  public static int calPoints(String[] ops) {
    Stack<Node> stack = new Stack<>();
    for (int i = 0; i < ops.length; i++) {
      String op = ops[i];
      if ("+".equals(op)) {
        if (!stack.isEmpty()) {
          Node pop = stack.pop();
          int r1 = pop.getResult();
          int r2 = null != pop.getNext() ? pop.getNext().getResult() : 0;
          int result = r1 + r2;
          stack.push(new Node(result, pop));
        }
      } else if ("D".equals(op)) {
        if (stack.isEmpty()) {
          continue;
        }
        Node pop = stack.pop();
        int result = pop.getResult();
        result = result * 2;
        stack.push(new Node(result, pop));
      } else if ("C".equals(op)) {
        if (stack.isEmpty()) {
          continue;
        }
        Node pop = stack.pop();
        stack.push(pop.getNext());
      } else {
        if (stack.isEmpty()) {
          Node node = new Node(Integer.valueOf(op));
          stack.push(node);
        } else {
          Node pop = stack.pop();
          int result = Integer.valueOf(op);
          stack.push(new Node(result, pop));
        }
      }
    }
    if (stack.isEmpty()) {
      return 0;
    }
    Node pop = stack.pop();
    int result = 0;
    while (pop != null) {
      result += pop.getResult();
      pop = pop.getNext();
    }
    return result;
  }
}

class Node {
  private int result;
  private Node next;

  public Node(int result) {
    this(result, null);
  }

  public Node(int result, Node next) {
    this.result = result;
    this.next = next;
  }

  public int getResult() {
    return result;
  }

  public void setResult(int result) {
    this.result = result;
  }

  public Node getNext() {
    return next;
  }

  public void setNext(Node next) {
    this.next = next;
  }
}
